package com.eulog.gwt.euloggwtlibrary.user.client.ui;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerCollection;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.SourcesMouseEvents;
import com.google.gwt.user.client.ui.Widget;

public class SwitchingImage extends Composite implements SourcesMouseEvents, SourcesClickEvents, HistoryListener, MouseEventListenerFromCollection {

	protected AbsolutePanel panel;
	
	protected Image masterImage;
	protected Image slaveImage;
	
	protected boolean isCurrentMaster; 
	protected boolean isMouseOver;
	protected boolean isSwitchImageMouseOver;
	protected boolean isSwitchImageClick;
	
	String link;
	
	private ClickListenerCollection clickListeners;
	private MouseListenerCollection mouseListeners;
	
	public SwitchingImage(Image a, Image b, boolean isImageAMaster, boolean isCurrentImageMaster, boolean _isSwitchImageMouseOver, boolean _isSwitchImageClick) {
		
		if(isImageAMaster) {
			masterImage = a;
			slaveImage = b;
		}
		else {
			masterImage = b;
			slaveImage = a;
		}
		
		isSwitchImageMouseOver=_isSwitchImageMouseOver;
		isSwitchImageClick=_isSwitchImageClick;
		
		panel = new AbsolutePanel();
				
		initWidget(panel);
		
		switchImage(isCurrentImageMaster,true);
		init();
	}
	
	private void init() {
		isMouseOver=false;
		panel.add(masterImage);
		panel.add(slaveImage);
		
		if(isSwitchImageMouseOver) sinkEvents(Event.MOUSEEVENTS);
		if(isSwitchImageClick) sinkEvents(Event.ONCLICK);
		
		panel.sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER);
		
		History.addHistoryListener(this);
	}
	
	public void switchImage(boolean toMaster, boolean forceChange) {
		
		if(forceChange || (isCurrentMaster != toMaster)) {
			isCurrentMaster = toMaster;
			swapImage(toMaster);
		}
	}
	
	private void swapImage(boolean toMaster) {
		if(toMaster) {
			slaveImage.setVisible(false);
			masterImage.setVisible(true);
		}
		else {
			slaveImage.setVisible(true);
			masterImage.setVisible(false);
		}
	}
	
	public void setHyperLink(String _link) {
        link = _link;
        sinkEvents(Event.ONCLICK);
	}
	
	public void onClickFromCollection(Widget sender) {
		switchImage(true,false);
	}
	
	public void onMouseEnterFromCollection(Widget sender) {
		onMouseLeave();
	}
	
	public void onMouseDownFromCollection(Widget sender, int x, int y) {}
	public void onMouseLeaveFromCollection(Widget sender) {}
	public void onMouseMoveFromCollection(Widget sender, int x, int y) {}
	public void onMouseUpFromCollection(Widget sender, int x, int y) {}
	
	
	private void onMouseEnter() {
		if(isCurrentMaster==true && isMouseOver==false) {
			swapImage(!isCurrentMaster);
			isMouseOver=true;
		}
	}
	
	private void onMouseLeave() {
		if(isCurrentMaster==true && isMouseOver==true) {
			swapImage(isCurrentMaster);
			isMouseOver=false;
		}
	}
	
	private void onClick() {
		if(link!=null) History.newItem(link);
		if(isSwitchImageClick) {
			switchImage(false, true);
		}
	}
	
	@Override
	public void onBrowserEvent(Event event) {
		super.onBrowserEvent(event);
		int eventBit = DOM.eventGetType(event);
		
		if(isSwitchImageMouseOver) {
			if(eventBit == Event.ONMOUSEOVER) onMouseEnter();
			else if(eventBit == Event.ONMOUSEOUT) onMouseLeave();
		}
		
		if(eventBit == Event.ONCLICK) onClick();
		
		switch (eventBit) {
		case Event.ONCLICK:
			if (clickListeners != null) {
				clickListeners.fireClick(this);
			}
			break;
			
		case Event.ONMOUSEDOWN:
		case Event.ONMOUSEUP:
		case Event.ONMOUSEMOVE:
		case Event.ONMOUSEOVER:
		case Event.ONMOUSEOUT: {
			if (mouseListeners != null) {
				mouseListeners.fireMouseEvent(this, event);
			}
			break;}
		}
	}
	
	public void addClickListener(ClickListener listener) {
		if (clickListeners == null) {
			clickListeners = new ClickListenerCollection();
			sinkEvents(Event.ONCLICK);
		}
		clickListeners.add(listener);
	}
	
	public void removeClickListener(ClickListener listener) {
		if (clickListeners != null) {
	    	clickListeners.remove(listener);
	    }
		
	}
	
	public void addMouseListener(MouseListener listener) {
		if (mouseListeners == null) {
			mouseListeners = new MouseListenerCollection();
			sinkEvents(Event.MOUSEEVENTS);
		}
		mouseListeners.add(listener);
	}
	
	public void removeMouseListener(MouseListener listener) {
		if (mouseListeners != null) {
			mouseListeners.remove(listener);
	    }
	}
	
	public void onHistoryChanged(String historyToken) {
		try {
			if (historyToken == link) {
				switchImage(false, true);
			}
		} catch (IndexOutOfBoundsException e) {
			
		}
	}
}